package zhou.chs.p9_3;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    TextView tv;  //显示读取到的寄存器值
    EditText et;  //编辑写入寄存器的值
    Button btread,btwrite,btrun,btmonitor; //按钮
    private SerialPort serialPort;      //声明串口
    private ReadThread mReadThread;    //读取线程
    private Handler myhandler;       //信息通道
    byte[] rbuf = new byte[256];  //串口接收数据缓冲区
    int len;    //接收区字节数
    String cmd; //待发送协议字符串
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)findViewById(R.id.idtv);   //实例化控件
        et = (EditText)findViewById(R.id.idet);
        btread = (Button) findViewById(R.id.idread);
        btwrite = (Button) findViewById(R.id.idwrite);
        btrun = (Button) findViewById(R.id.idrun);
        btmonitor = (Button) findViewById(R.id.idmonitor);
        btread.setOnClickListener(this);    //注册按钮单击事件
        btwrite.setOnClickListener(this);
        btrun.setOnClickListener(this);
        btmonitor.setOnClickListener(this);
        serialPort = new SerialPort();   //创建串口
        //打开串口1，串口参数：9600,n,8,1
        serialPort.open("COM1",9600, 8, "N", 1);
        mReadThread = new ReadThread();   //声明串口接收数据线程
        mReadThread.start();    //启动串口接收数据线程
        myhandler = new MyHandler();     //实例化Handler，用于进程间的通信
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.idread:  //读取按钮
                cmd = "@00RD00000005";   //从D0开始读取5个寄存器的数据
                break;
            case R.id.idwrite:  //写入按钮
                cmd = "@00WD0010"+et.getText().toString();   //从D10开始写寄存器数据
                break;
            case R.id.idrun:    //运行按钮
                cmd = "@00SC03";   //进入运行状态
                break;
            case R.id.idmonitor:    //监视按钮
                cmd = "@00SC02";   //进入监视状态
                break;
        }
        cmd = cmd + String.format("%02X", FCS(cmd)) + "*\r";  //加校验及结束符
        int n = cmd.length();
        byte[] tbuf = cmd.getBytes();
        serialPort.write(tbuf,n);   //发送协议数据
    }
    //读取数据的线程
    private class ReadThread extends Thread {
        @Override
        public void run() {
            super.run();
            byte[] buff = new byte[32];
            while(true){
                try {
                    int n = serialPort.read(buff,32,100);  //接收数据
                    if(n > 0) {
                        for (int i=0;i<n;i++){
                            rbuf[i] = buff[i];    //保存数据
                        }
                        try {
                            sleep(100);     //延时100ms，等1帧数据接收完成
                        } catch (InterruptedException e) {
                        }
                        int m = serialPort.read(buff,32,100);  //接收数据
                        for (int i=0;i<m;i++){
                            rbuf[i+n] = buff[i];    //保存数据
                        }
                        Message msg = myhandler.obtainMessage();
                        msg.obj = m+n;
                        msg.what = 0;
                        myhandler.sendMessage(msg);  //收到数据，发送消息
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //在主线程处理Handler传回来的message
    class MyHandler extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:     //收到串口数据
                    len = Integer.parseInt(msg.obj.toString());  //获取数据长度
                    String s = new String(rbuf);
                    s = s.substring(0,len);  //响应帧内容
                    //如果是返回数据，则只显示数据内容
                    if(s.indexOf("RD") != -1) s = s.substring(7,len-4);
                    tv.setText(s);
                    break;
            }
        }
    }
    // 生成FCS校验码
    private byte FCS(String s){
        byte m= (byte)s.charAt(0);
        int n = s.length();
        for(int i=1;i<n;i++){
            m = (byte) (m^(byte)s.charAt(i)); //异或运算
        }
        return m;
    }
    @Override   //程序退出前关闭串口
    protected void onDestroy() {
        super.onDestroy();
        serialPort.close();
    }
}
